<template>
    <div :class="propJson.editFlag ? 'formContainer' : 'formContainerCommon'">
        <el-form :inline="propJson.isInline" v-if="reloadFlag" :model="containerForm" :rules="componentRules" style="width: 100%" ref="formRef" :class="propJson.isInline ? 'inlineClass' : 'commonClass'">
            <el-form-item v-if="!propJson.editFlag" :label="itemInfo.label" :label-width="propJson.labelLength" :prop="itemInfo.labelEn"  class="itemClassCommon"
                          v-for="itemInfo in sourceFormList" :key="itemInfo.id">
                <component :is="itemInfo.component" :propJson="itemInfo.propJson" :commonParam="commonParam" style="width: 100%">
                    <template v-slot:[itemSlot.slotName]="slotProps" v-for="itemSlot in slotList">
                        <slot :name="itemSlot.slotName" :slotProps="slotProps"></slot>
                    </template>
                </component>
            </el-form-item>

            <el-form-item v-if="!propJson.editFlag && propJson.isInline">
                <el-button v-if="propJson.showButtons.includes('Cancel')" :icon="propJson.cancelIcon" @click="cancelSubmit()">{{propJson.cancelName ? propJson.cancelName : '取消'}}</el-button>
                <el-button v-if="propJson.showButtons.includes('Reset')" :icon="propJson.resetIcon" @click="resetForm()">{{propJson.resetName ? propJson.resetName : '重置'}}</el-button>
                <el-button type="primary" :loading="submitLoading" :icon="propJson.submitIcon" v-if="propJson.showButtons.includes('Submit')" @click="submitForm(formRef)">{{propJson.submitName ? propJson.submitName : '提交'}}</el-button>
            </el-form-item>

            <draggable v-if="propJson.editFlag"
                       :list="propJson.list"
                       animation="300"
                       :force-fallback="true"
                       :group="{name:'lowcode'}"
                       item-key="id"
                       style="margin-top: 30px; margin-bottom: 30px"
            >
                <template #item="{ element }">
                    <el-form-item class="itemClass" :label="element.label" :prop="element.labelEn" :label-width="propJson.labelLength" :computeIsShow="computeIsShow">
                        <component :is="element.component" :propJson="element.propJson" v-if="itemFlag" :commonParam="commonParam" @click.stop="" @dblclick.stop="changeComponentInfo(element)" style="width: 100%"/>
                        <component is="CloseCircleOutlined" class="closeClass" @click.stop="" @dblclick.stop="deleteComponent(element)"/>
                    </el-form-item>
                </template>
            </draggable>

            <div class="formSubmitButton" v-if="propJson.editFlag || !propJson.isInline">
                <el-button v-if="propJson.showButtons.includes('Cancel')" :icon="propJson.cancelIcon" @click="cancelSubmit()">{{propJson.cancelName ? propJson.cancelName : '取消'}}</el-button>
                <el-button v-if="propJson.showButtons.includes('Reset')" :icon="propJson.resetIcon" @click="resetForm()">{{propJson.resetName ? propJson.resetName : '重置'}}</el-button>
                <el-button type="primary" :loading="submitLoading" :icon="propJson.submitIcon" v-if="propJson.showButtons.includes('Submit')" @click="submitForm(formRef)">{{propJson.submitName ? propJson.submitName : '提交'}}</el-button>
            </div>
        </el-form>
    </div>
</template>

<script name="GlobalFormComponent" setup lang="ts">
import {deepCopy} from "@/utils/ywuCommon";
import {getCommonParamObj, sleep} from "@/utils/commonParamUtil";
import {ElNotification, FormInstance} from "element-plus";
import {doThirdServiceAction} from "@/utils/lowcode/thirdService";
import {getFromAssociationFlag} from "@/utils/lowcode/formDataAssociation";
import {ref, computed, defineProps, watch} from "vue";
import {useLowCodeStore} from "@/stores/lowcode/lowcode";

let props = defineProps(['propJson', 'commonParam']);

let propJson = computed(() => {return props['propJson']})
let commonParam = computed(() => {return props['commonParam']})

let containerForm = ref({});
let itemFlag = ref(true);
let submitLoading = ref(false);
let reloadFlag = ref(true);
let sourceFormList = ref([]);

let componentRules = computed(() => {
    let res = {}
    let itemList = propJson.value.list;
    for (let i = 0; i < itemList.length; i++) {
        let itemInfo = itemList[i];
        if (itemInfo.isMust) {
            // 必填的字段需要添加校验对象
            res[itemInfo.labelEn] = [{ required: true, message: `${itemInfo.mustTipContent}`, trigger: 'blur' }];
        }
    }
    // 设置containerForm
    for (let i = 0; i < itemList.length; i++) {
        let itemInfo = itemList[i];
        if (itemInfo.isMust) {
            // 将绑定的参数对象设置到
            let commonParamList = commonParam.value;
            for (let j = 0; j < commonParamList.length; j++) {
                let commonParamInfo = commonParamList[j];
                if (commonParamInfo.variableName === itemInfo.propJson.bindVariable) {
                    containerForm.value[itemInfo.labelEn] = commonParamInfo.variableValue
                }
            }
        }
    }
    return res;
})

let slotList = computed(() => {
    let res = getCommonParamObj(commonParam.value, "templateSlotInfo")
    return res.variableValue;
})

// 计算当前组件是否可展示
computeIsShow();

function changeComponentInfo(element) {
    let lowCodeStore = useLowCodeStore();
    lowCodeStore.resetCurrentDrawer(element.drawerComponent)
    lowCodeStore.resetCurrentDrawerElementId(element.id);
    lowCodeStore.resetCurrentDrawerTitle(element.title)
    let copyJson = deepCopy(element.propJson)
    lowCodeStore.resetLowCodeDrawerJsonInfo(copyJson);
    lowCodeStore.resetIsShowDrawer(true)
    lowCodeStore.resetLowCodeComponentList(propJson.value.list)
}

function deleteComponent(element) {
    let index = -1;
    // 遍历当前列表，删除元素ID对应的数据
    for (let i = 0; i < propJson.value.list.length; i++) {
        if (propJson.value.list[i].id === element.id) {
            index = i;
        }
    }
    if (index >= 0) {
        propJson.value.list.splice(index, 1);
    }
}

async function cancelSubmit() {
    // 定义一个标志位，后续同步执行
    let awaitObj = {flag: false, res: true}
    await doThirdServiceAction(propJson.value.formCancelAction, awaitObj, commonParam.value, ()=>{}, ()=>{}, null);
}

let formRef = ref<FormInstance>()
function submitForm(formEl: FormInstance | undefined) {
    if (!formEl) return
    formEl.validate(async (valid) => {
        if (valid) {
            submitLoading.value = true
            // 定义一个标志位，后续同步执行
            let awaitObj = {flag: false, res: true}
            await doThirdServiceAction(propJson.value.formSubmitAction, awaitObj, commonParam.value, ()=>{}, ()=>{}, null);
            await resetLoad(awaitObj);
        }
    })
}

async function resetLoad(awaitObj) {
    if (awaitObj.res) {
        if (propJson.value.isShowSuccessFlag) {
            ElNotification({
                title: 'Success',
                message: "成功",
                type: 'success'
            });
        }
    } else {
        ElNotification({
            title: 'Error',
            message: "失败",
            type: 'error'
        });
    }
    submitLoading.value = false
}

function resetForm() {

}

function computeIsShow() {
    let formList = propJson.value.list;
    let tempList = [];
    for (let index = 0; index < formList.length; index++) {
        let formInfo = formList[index];
        let ruleInfo = formInfo.ruleInfo;
        if (!ruleInfo || !ruleInfo.ruleInfoList || ruleInfo.ruleInfoList.length === 0) {
            tempList.push(formInfo);
            continue;
        }
        let res = getFromAssociationFlag(ruleInfo, commonParam.value);
        if (res) {
            tempList.push(formInfo);
        }
    }
    sourceFormList.value = tempList;
    reloadFlag.value = false;
    reloadFlag.value = true;
}

watch(commonParam, (newVal, oldVal) => {
    computeIsShow();
}, {deep: true});
</script>

<style scoped lang="less">
.formContainer {
    width: 96%;
    padding-left: 2%;
    padding-right: 2%;
    transition: box-shadow 0.3s ease;
    //去除光标
    caret-color: transparent;
    overflow: auto;
    .itemClass {
        position: relative;
        transition: box-shadow 0.3s ease;
        margin-bottom: 0.3%;
        .closeClass {
            display: none;
        }
    }
    .itemClassCommon {
        width: 200px;
        position: relative;
        transition: box-shadow 0.3s ease;
        margin-bottom: 0.3%;
        .closeClass {
            display: none;
        }
    }
    .itemClass:hover {
        cursor: pointer;
        box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.5);
        .closeClass {
            position: absolute;
            color: #e76565;
            top: 2px;
            right: 2px;
            display: block;
        }
    }
}
.formContainer:hover {
    cursor: pointer;
}

.formContainerCommon {
    width: 100%;
    .itemClass {
        margin-bottom: 0.3%;
    }
}

.formSubmitButton {
    display: flex;
    align-items: center;
    justify-content: center;
}

.inlineClass ::v-deep .el-form-item__content {
    width: 300px;
}
</style>